﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//WB Added
using umbraco.cms.businesslogic.packager.standardPackageActions;
using umbraco.interfaces;
using System.Web.Configuration;
using System.Configuration;
using System.Xml;
using System.Web;


namespace DictionaryTranslate
{
    public class AddSystemServiceModel : IPackageAction
    {
        public bool Execute(string packageName, XmlNode xmlData)
        {

            //Flags to check if updated <bindings> or <client>
            bool updatedBindings;
            bool updatedClient;

            string webConfigFilePath = HttpContext.Current.Server.MapPath("~/web.config");

            try
            {
                //Load the web.config as XML doc
                XmlDocument webConfig = new XmlDocument();
                webConfig.Load(webConfigFilePath);

                //Check if <system.serviceModel> does NOT exist
                if (webConfig.SelectSingleNode("//system.serviceModel") == null)
                {

                    XmlNode serviceModelXML = xmlData.SelectSingleNode("//system.serviceModel");

                    //Update web.config
                    //webConfig.SelectSingleNode("//configuration").AppendChild(xmlData);
                    webConfig.SelectSingleNode("//configuration").AppendChild(webConfig.ImportNode(serviceModelXML, true));

                    //Update both flags
                    updatedBindings     = true;
                    updatedClient       = true;
                }
                else
                {
                    //<system.serviceModel> DOES exist


                    //Check if <bindings> does NOT exist
                    if (webConfig.SelectSingleNode("//system.serviceModel/bindings") == null)
                    {
                        //No it does not exist - lets insert (including) <bindings> xmlData snippet
                        XmlNode bindingsXML = xmlData.SelectSingleNode("//bindings");

                        //Update web.config
                        //webConfig.SelectSingleNode("//system.serviceModel").AppendChild(bindingsXML);
                        webConfig.SelectSingleNode("//system.serviceModel").AppendChild(webConfig.ImportNode(bindingsXML, true));

                        //Update flag
                        updatedBindings = true;
                    }

                    //Check if <basicHttpBinding> node does not exist
                    if (webConfig.SelectSingleNode("//system.serviceModel/bindings/basicHttpBinding") == null)
                    {
                        //No it does not exist - lets insert (including) <basicHttpBinding> xmlData snippet
                        XmlNode basicHttpXML = xmlData.SelectSingleNode("//basicHttpBinding");

                        //Update web.config
                        //webConfig.SelectSingleNode("//system.serviceModel/bindings").AppendChild(basicHttpXML);
                        webConfig.SelectSingleNode("//system.serviceModel/bindings").AppendChild(webConfig.ImportNode(basicHttpXML, true));

                        //Update flag
                        updatedBindings = true;
                    }
                    else
                    {
                        //Yes it does exist <basicHttpBinding>

                        //Insert <binding> node as this won't exist !
                        XmlNode bindingXML = xmlData.SelectSingleNode("//binding");

                        //Update web.config
                        //webConfig.SelectSingleNode("//system.serviceModel/bindings/basicHttpBinding").AppendChild(bindingXML);
                        webConfig.SelectSingleNode("//system.serviceModel/bindings/basicHttpBinding").AppendChild(webConfig.ImportNode(bindingXML, true));

                        //Update flag
                        updatedBindings = true;
                    }

                    //Check if <client> node does not exist
                    if (webConfig.SelectSingleNode("//system.serviceModel/client") == null)
                    {
                        //No it does not exist - lets insert (including) <client> xmlData snippet
                        XmlNode clientXML = xmlData.SelectSingleNode("//client");

                        //Update web.config
                        //webConfig.SelectSingleNode("//system.serviceModel").AppendChild(clientXML);
                        webConfig.SelectSingleNode("//system.serviceModel").AppendChild(webConfig.ImportNode(clientXML, true));

                        //Update flag
                        updatedClient = true;
                    }
                    else
                    {
                        //Yes it does exist <client>

                        //Insert <endpoint> node as this wont exist inside client node
                        XmlNode endpointXML = xmlData.SelectSingleNode("//endpoint");

                        //Update web.config
                        //webConfig.SelectSingleNode("//system.serviceModel/client").AppendChild(endpointXML);
                        webConfig.SelectSingleNode("//system.serviceModel/client").AppendChild(webConfig.ImportNode(endpointXML, true));

                        //Update flag
                        updatedClient = true;
                    }

                }
                


                //Save changes to web.config
                webConfig.Save(webConfigFilePath);


                //Check that both flags are true
                if(updatedBindings == true && updatedClient == true)
                {
                    //Let umbraco know it went OK
                    return true;
                }
                else
                {
                    //Say to umbraco it did not install
                    return false;
                }                
            }
            catch (Exception exception)
            {
                //There was some excpetion so lets umbraco know it didnt go well
                return false;
            }
        }

        public string Alias()
        {
            return "AddSystemServiceModel";
        }

        public bool Undo(string packageName, XmlNode xmlData)
        {
            //Flags to check if updated <bindings> or <client>
            bool removedBindings;
            bool removedClient;

            string webConfigFilePath = HttpContext.Current.Server.MapPath("~/web.config");

            try
            {

                //Load the web.config as XML doc
                XmlDocument webConfig = new XmlDocument();
                webConfig.Load(webConfigFilePath);


                //Get binding name attribute from xmlData
                string bindingNameAttribute = xmlData.SelectSingleNode("//binding").Attributes["name"].Value;

                //Select <binding> node in web.config where the name attrbute matches bindingNameAttribute
                XmlNode bindingNodeXML = webConfig.SelectSingleNode("//binding [@name='" + bindingNameAttribute +"']");

                //Check <binding> with name="BasicHttpBinding_LanguageService" exists
                if (bindingNodeXML != null)
                {
                    //Lets try to remove this
                    webConfig.SelectSingleNode("//system.serviceModel/bindings/basicHttpBinding").RemoveChild(bindingNodeXML);

                    //Update flag
                    removedBindings = true;
                }
                else
                {
                    //Already removed - update flag
                    removedBindings = true;
                }



                //Get endPoint name attribute from xmlData
                string endPointNameAttribute = xmlData.SelectSingleNode("//endpoint").Attributes["name"].Value;

                //Select <endpoint> node in web.config where the name attrbute matches endPointNameAttribute
                XmlNode endPointNodeXML = webConfig.SelectSingleNode("//endpoint [@name='" + endPointNameAttribute + "']");

                //Check <endpoint> with name="BasicHttpBinding_LanguageService" exists
                if (endPointNodeXML != null)
                {
                    //Lets try to remove this
                    webConfig.SelectSingleNode("//system.serviceModel/client").RemoveChild(endPointNodeXML);

                    //Update flag
                    removedClient = true;
                }
                else
                {
                    //Already removed - update flag
                    removedClient = true;
                }


                //Save changes to web.config
                webConfig.Save(webConfigFilePath);


                //Check that both flags are true
                if (removedBindings == true && removedClient == true)
                {
                    //Let umbraco know it went OK
                    return true;
                }
                else
                {
                    //Say to umbraco it did not install
                    return false;
                }        

            }
            catch
            {
                //There was some excpetion so lets umbraco know it didnt go well
                return false;
            }
        }

        public XmlNode SampleXml()
        {
            var sample =
                "<Action runat=\"install\" undo=\"true/false\" alias=\"AddSystemServiceModel\">"
                    + "<system.serviceModel>"
                        + "<bindings>"
                            + "<basicHttpBinding>"
                                + "<binding name=\"BasicHttpBinding_LanguageService\" " 
                                    + "closeTimeout=\"00:01:00\" "
                                    + "openTimeout=\"00:01:00\" "
                                    + "receiveTimeout=\"00:10:00\" " 
                                    + "sendTimeout=\"00:01:00\" "
                                    + "allowCookies=\"false\" "
                                    + "bypassProxyOnLocal=\"false\" "
                                    + "hostNameComparisonMode=\"StrongWildcard\" "
                                    + "maxBufferSize=\"65536\" "
                                    + "maxBufferPoolSize=\"524288\" "
                                    + "maxReceivedMessageSize=\"65536\" "
                                    + "messageEncoding=\"Text\" "
                                    + "textEncoding=\"utf-8\" "
                                    + "transferMode=\"Buffered\" "
                                    + "useDefaultWebProxy=\"true\">"
                                        + "<readerQuotas maxDepth=\"32\" "
                                            + "maxStringContentLength=\"8192\" "
                                            + "maxArrayLength=\"16384\" "
                                            + "maxBytesPerRead=\"4096\" "
                                            + "maxNameTableCharCount=\"16384\" />"
                                        + "<security mode=\"None\">"
                                            + "<transport clientCredentialType=\"None\" "
                                                + "proxyCredentialType=\"None\" "
                                                + "realm=\"\">"
                                                    + "<extendedProtectionPolicy policyEnforcement=\"Never\" />"
                                            + "</transport>"
                                            + "<message clientCredentialType=\"UserName\" algorithmSuite=\"Default\" />"
                                        + "</security>"
                                + "</binding>"
                            + "</basicHttpBinding>"
                        + "</bindings>"
                        + "<client>"
                            + "<endpoint address=\"http://api.microsofttranslator.com/v1/Soap.svc\" "
                                + "binding=\"basicHttpBinding\" "
                                + "bindingConfiguration=\"BasicHttpBinding_LanguageService\" "
                                + "contract=\"TranslatorService.LanguageService\" "
                                + "name=\"BasicHttpBinding_LanguageService\" />"
                        + "</client>"
                    + "</system.serviceModel>"
                + "</Action>";

            return helper.parseStringToXmlNode(sample);
        }
    }
}
